package com.sun;

import java.util.ArrayList;
import java.util.List;

/**
 * https://leetcode.cn/problems/generate-parentheses/
 * 数字 n 代表生成括号的对数，请你设计一个函数，用于能够生成所有可能的并且 有效的 括号组合。
 */
public class Test22括号生成 {
    public static void main(String[] args) {
        Test22括号生成 test22 = new Test22括号生成();
        List<String> strings = test22.generateParenthesis3(2);
        strings.forEach(System.out::println);
    }

    /**
     * 方法一：力扣官方，暴力生成法
     */
    public List<String> generateParenthesis1(int n){
        List<String> res = new ArrayList<>();
        char[] currnet = new char[2*n];
        generateAll(currnet, 0, res);
        return res;
    }
    public void generateAll(char[] current, int pos, List<String> res){
        if (pos == current.length){
            if (isValid(current)) res.add(new String(current));
        }else {
            current[pos] = '(';
            generateAll(current, pos + 1, res);
            current[pos] = ')';
            generateAll(current,pos + 1, res);
        }
    }

    public boolean isValid(char[] current){
        int balance = 0;
        for (char c : current) {
            if(c == '('){
                balance++;
            }else {
                balance--;
            }
            if (balance < 0){
                return false;
            }
        }
        return balance == 0;
    }


    /**
     * 方法二：力扣官方，回溯方法，对方法一的改进
     */
    public List<String> generateParenthesis2(int n) {
        List<String> ans = new ArrayList<String>();
        backtrack(ans, new StringBuilder(), 0, 0, n);
        return ans;
    }

    public void backtrack(List<String> ans, StringBuilder cur, int open, int close, int max) {
        if (cur.length() == max * 2) {
            ans.add(cur.toString());
            return;
        }
        if (open < max) {
            cur.append('(');
            backtrack(ans, cur, open + 1, close, max);
            cur.deleteCharAt(cur.length() - 1);
        }
        if (close < open) {
            cur.append(')');
            backtrack(ans, cur, open, close + 1, max);
            cur.deleteCharAt(cur.length() - 1);
        }
    }
    /**
     * 方法三：
     */
    public List<String> generateParenthesis3(int n) {
        return generate(n);
    }

    public  List<String> generate(int n) {
        ArrayList[] cache = new ArrayList[100];
        if (cache[n] != null) {
            return cache[n];
        }
        ArrayList<String> ans = new ArrayList<String>();
        if (n == 0) {
            ans.add("");
        } else {
            for (int c = 0; c < n; ++c) {
                for (String left: generate(c)) {
                    for (String right: generate(n - 1 - c)) {
                        ans.add("(" + left + ")" + right);
                    }
                }
            }
        }
        cache[n] = ans;
        return ans;
    }

}
